package menu
{
	import com.*;
	import com.Logging.ClientAction;
	import com.Logging.ClientActionType;
	import data.*;
	import events.GCEvent;
	import events.GCUpgradeEvent;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.utils.Dictionary;
	import ui.button.GCButton;
	import ui.GCShipStatsArea;
	import ui.GCShipUpgradesArea;
	import ui.popup.GCCostPopup;
	import ui.popup.GCTextPopup;
	import ui.textfield.GCStylizedText;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;

	
	import org.flixel.*;
	
	/**
	 * ...
	 * @author Jason Won
	 */
	public class GCShipRepairMenu extends Sprite implements GCSuperMenu
	{
		// Related to the ship appearance
		private var _shipImage:Sprite;	
		private var _shipImageBackground:Sprite;
		
		// The area where upgrades can be viewed
		private var _shipUpgradesLabel:GCStylizedText;
		private var _shipUpgradesArea:GCShipUpgradesArea;
		
		// Display current stats of the ship
		private var _shipStatsDisplay:GCShipStatsArea;
		
		// Allow player to leave the menu
		private var _exitButton:GCButton;
		
		// The current ship we are examining
		private var _currentShip:GCShip;
		
		// HACK we save the coordinates of the ship image from where it
		// was on the world map.
		private var _savedCoordinate:Point;
		
		// Tutorial
		private var _firstTimeEntered:Boolean;
		
		/*
		 * Background 
		 */
		private var _backgroundImage:Sprite;
		
		public function GCShipRepairMenu() 
		{
			/*
			// Equipped upgrades
			//-- with on hover description

			// Ship stats
			// health (+ a button to restore health), max hull capacity, speed
			
			// List of upgrades
			// --> able to drag the upgrades to and from the equipped upgrades 
			// --> with on hover descriptions of each equips
			*/
			
			// Background
			var background:Bitmap = GCResources.getResource("main_background");
			this.addChild(background);
			
			//_shipImage = new Sprite();
			_shipImageBackground = new Sprite();
			_shipUpgradesLabel = new GCStylizedText();
			_shipUpgradesArea = new GCShipUpgradesArea();
			_shipStatsDisplay = new GCShipStatsArea();
			_exitButton = new GCButton(onExitMenu);
			
			_firstTimeEntered = true;
			
			init();
		}
		
		private function init():void
		{
			var shipBack:Sprite = GCResources.getMaskedCanvasBackground(300, 300);
			_shipImageBackground.addChild(shipBack);
			_shipImageBackground.x = 10;
			_shipImageBackground.y = 10;
			
			_shipUpgradesArea.addEventListener(GCEvent.UPGRADE_CHANGED_EVENT, onUpgradeAltered);			
			
			_shipStatsDisplay.x = this.width - _shipStatsDisplay.width - 10;
			_shipStatsDisplay.y = 10;
			
			_shipUpgradesArea.y = this.height - 200;
			
			_exitButton.loadGraphic(GCResources.plate, 150, 30);
			_exitButton.loadText("Leave Ship Menu");
			_exitButton.x = 600;
			_exitButton.y = 480;
			
			this.addChild(_shipUpgradesArea);
			this.addChild(_shipImageBackground);
			this.addChild(_shipStatsDisplay);
			this.addChild(_exitButton);
			
			_shipUpgradesLabel.text = "Click on a slot to Add/Remove upgrades";
			_shipUpgradesLabel.setBgStyle(GCStylizedText.STYLE_NONE, 200, 30);
			_shipUpgradesLabel.x = 0;
			_shipUpgradesLabel.y = _shipUpgradesArea.y - _shipUpgradesLabel.height;
			this.addChild(_shipUpgradesLabel);
			
			// Background
			_backgroundImage = GCResources.getMaskedCanvasBackground(300, 300);
			_backgroundImage.x = 10;
			_backgroundImage.y = 10;
			this.addChildAt(_backgroundImage, 0);			
		}
		
		/**
		 * Here we will need to set up the stats and upgrades to render correctly
		 * for the given ship. Many tasks need to be done here, we will need to first
		 * get the appropriate image of the ship and overlay the upgrades on that image.
		 * Ugh, we do this every single time open is called
		 * 
		 * We will also need to layout the upgrades in the UI, allowing the player to select
		 * new ones to add and remove to specific slots.
		 * 
		 * Finally we will need to display the current stats of the ship.
		 * 
		 * @param	myShip
		 */
		public function openMenu(myShip:GCShip):void
		{
			var upgrades:Dictionary = myShip.upgradeSlots;
			
			/*
			 * Paste the appropriate upgrades in the ship as UI components
			 */
			for (var obj:Object in upgrades)
			{
				var slot:uint = obj as uint;
				var item:uint = upgrades[slot];
				trace("Adding a new upgrade sprite");
				_shipUpgradesArea.addNewSlot(slot, item);
			}
			
			_currentShip = myShip;
			
			/*
			 * Display the ship statistics
			 */
			_shipStatsDisplay.initializeStats(_currentShip._stats);
												
			/*
			 * Get the image and paste a zoomed in version of it.
			 */
			_shipImage = _currentShip.shipImage;
			_savedCoordinate = new Point(_shipImage.x, _shipImage.y);
			_shipImage.width = 300;
			_shipImage.height = 300;
			_shipImage.x = 0;
			_shipImage.y = 0;
			_shipImageBackground.addChild(_shipImage);
			
			/*
			 * Roy-- tutorial
			 */
			if (GCPlayState.tutorialSequence.currentTutorialStage == GCTutorial.STAGE_ESTABLISH_NEW_CENTER && _firstTimeEntered)
			{
				_firstTimeEntered = false;
				var description:String = "You can customize your ship with a number of upgrades that alter it's stats! " +
					"Upgrades can help you carry more items on your ship or allow you to travel to new places.\nClick on an empty slot to see what upgrades you can add to your ship.";
				GCPlayState.disableScreen(new GCTextPopup(description, GCPlayState.enableScreen));
			}
		}
		
		public function closeMenu():void
		{
			/*
			 * Zoom back out on the ship image and restore its previous
			 * coordinates.
			 */
			_shipImage.width = 100;
			_shipImage.height = 100;
			_shipImage.x = _savedCoordinate.x;
			_shipImage.y = _savedCoordinate.y;
			
			/*
			 * Clean up the rest of the menu
			 */
			_shipUpgradesArea.cleanArea();
			_shipImageBackground.removeChild(_shipImage);
		}
		
		//----------------------------------------------------------------------
		//	EVENT HANDLERS
		//----------------------------------------------------------------------
		private function onUpgradeAltered(event:GCUpgradeEvent):void
		{
			// This is the item id of the item to put on the new slot
			// (it is 0 if we are removing an upgrade)
			var itemId:uint = event.upgradeItemId;
			var slotId:uint = event.upgradeSlotId;
			var o:Object = new Object();
			if (event.upgradeAction == GCUpgradeEvent.ADD_UPGRADE_EVENT)
			{
				trace("Adding upgrade effects to actual ship");
				
				// Add visually if the image can be put there
				if (GCItemData.getUpgradePositionFromId(itemId, _currentShip.getType()) != null)
					_currentShip.attachVisually(slotId, itemId);
				_currentShip.addUpgrade(slotId, itemId);
				
				GCPlayState.getPlayerInventory().removeFromInventory(itemId, 1);
				
				/*
				 * Roy -- tutorial
				 * checking that an upgrade was added to the ship
				 */
				if (GCPlayState.tutorialSequence.currentTutorialStage == GCTutorial.STAGE_ESTABLISH_NEW_CENTER)
				{
					var template:uint = GCQuestData.QUEST_TEMPLATE_TUTORIAL_16;
					var quest:GCQuest = GCPlayState.tutorialSequence.getTutorialQuestFromTemplate(template);
					if (quest != null)
					{
						GCPlayState.dispatchTutorialComplete(template);
					}
				}
				
				// Special case where we must add new upgrade sprites
				var enhancements:Dictionary = GCItemData.getUpgradeEnhancementsFromId(itemId);
				if (enhancements[GCShipData.STAT_SLOTS] != null)
				{
					var numSlotsToAdd:uint = enhancements[GCShipData.STAT_SLOTS];
					for (var i:uint = 0; i < numSlotsToAdd; i++)
					{
						var newSlotId:uint = _currentShip._stats[GCShipData.STAT_SLOTS] - i;
						
						// Notify the database that a new upgrade slot should be added
						// Boosted stats should remain the same
						GCUtil.equipItemToShip(_currentShip.shipId, newSlotId, 0, _currentShip.boosts[GCShipData.STAT_HULL], 
							_currentShip.boosts[GCShipData.STAT_DEFENSE], _currentShip.boosts[GCShipData.STAT_SPEED], _currentShip.boosts[GCShipData.STAT_NAVIGATION],
							_currentShip.boosts[GCShipData.STAT_SLOTS], 0, function(code:uint, data:Object):void { } );
							
						_shipUpgradesArea.addNewSlot(newSlotId);
					}
				}
				
				if (GCConstants.LOGGING_DATA)
				{
					o["itemId"] = itemId;
					o["slotId"] = slotId;
					o["shipType"] = this._currentShip.getType();
					GCPlayState.logger.LogAction(new ClientAction(ClientActionType.ATTACH_UPGRADE, o));
				}
			}
			else if (event.upgradeAction == GCUpgradeEvent.DISCARD_UPGRADE_EVENT)
			{
				trace("Removing upgrade effects from actual ship");
				
				// Remove visually if it can be placed on ship
				if (GCItemData.getUpgradePositionFromId(_currentShip.upgradeSlots[slotId], _currentShip.getType()) != null)
					_currentShip.removeVisually(slotId);
				_currentShip.removeUpgrade(slotId);
				
				if (GCConstants.LOGGING_DATA)
				{
					o["itemId"] = itemId;
					o["slotId"] = slotId;
					o["shipType"] = this._currentShip.getType();
					GCPlayState.logger.LogAction(new ClientAction(ClientActionType.DETACH_UPGRADE, o));
				}
			}
			
			/*
			 * Show the updated stats of the ship.
			 */
			_shipStatsDisplay.initializeStats(_currentShip._stats);
		}
		
		private function onExitMenu(event:MouseEvent):void
		{
			dispatchEvent(new GCEvent(GCEvent.EXIT_MENU_EVENT));
		}
		
		//----------------------------------------------------------------------
		//	SUPER MENU FUNCTIONS
		//----------------------------------------------------------------------
		
		/**
		 * Method to call to refresh any dynamic parts on the menu
		 */
		public function refresh():void
		{
			closeMenu();
			openMenu(GCPlayState.getCurrentShip());
		}
		
		/**
		 * Method to enable list displays to scroll
		 */
		public function enableScrolling():void
		{
			
		}
		
		/**
		 * Method to disable list displays from scrolling
		 */
		public function disableScrolling():void
		{
			
		}
		
	}
}